ফোরট্রানে Linked List এবং Dynamic Data Structures
Linked List এবং অন্যান্য Dynamic Data Structures (যেমন স্ট্যাক, কিউ, গ্রাফ ইত্যাদি) ফোরট্রানে ডায়নামিক মেমরি ব্যবস্থাপনা ব্যবহার করে ডেটা সংরক্ষণ এবং পরিচালনার অত্যন্ত গুরুত্বপূর্ণ ধারণা। এই ধরনের ডেটা স্ট্রাকচারগুলি সাধারণ অ্যারে ডেটা স্ট্রাকচারগুলির তুলনায় বেশি নমনীয় এবং মেমরি ব্যবহারে আরও দক্ষ। এর মাধ্যমে ডেটাকে একে একে সন্নিবেশিত (insert) এবং মুছে ফেলা (delete) সম্ভব হয়, যা অ্যারে ব্যবস্থায় খুবই সীমিত।
১. Linked List কী?
Linked List হলো একটি ডেটা স্ট্রাকচার, যেখানে প্রতিটি উপাদান (node) দুটি অংশে বিভক্ত: একটি ডেটা অংশ এবং একটি পয়েন্টার অংশ (যা পরবর্তী উপাদানের ঠিকানা ধারণ করে)। এটি একটি ডায়নামিক ডেটা স্ট্রাকচার কারণ এতে মেমরি বরাদ্দ এবং মুক্ত করা রানটাইমে (runtime) হতে পারে।
Linked List এর উপাদান:
- Node: প্রতিটি উপাদান (node) একটি ডেটা অংশ এবং একটি পরবর্তী node এর পয়েন্টার ধারণ করে।
- Head: লিঙ্কড লিস্টের প্রথম উপাদান।
- Tail: লিঙ্কড লিস্টের শেষ উপাদান, যার পরবর্তী node পয়েন্টার NULL থাকে।
২. ফোরট্রানে Linked List তৈরি করা
ফোরট্রানে লিঙ্কড লিস্ট তৈরি করতে ALLOCATABLE টাইপের ডেটা স্ট্রাকচার এবং পয়েন্টার ব্যবহার করা হয়। একটি সাধারিত লিঙ্কড লিস্টের উদাহরণ দেখানো হলো।
উদাহরণ: সিঙ্গল লিঙ্কড লিস্ট (Singly Linked List)
PROGRAM linked_list_example
TYPE Node
INTEGER :: data
POINTER :: next_node => NULL()
END TYPE Node
TYPE(Node), POINTER :: head, temp, new_node
INTEGER :: value
! লিঙ্কড লিস্টের প্রথম উপাদান তৈরি করা
ALLOCATE(head)
head%data = 10
head%next_node => NULL()
! নতুন উপাদান যোগ করা
PRINT *, 'Enter a value to insert: '
READ *, value
ALLOCATE(new_node)
new_node%data = value
new_node%next_node => NULL()
! পুরানো লিঙ্কড লিস্টের শেষে নতুন উপাদান যুক্ত করা
temp => head
DO WHILE (ASSOCIATED(temp%next_node))
temp => temp%next_node
END DO
temp%next_node => new_node
! লিঙ্কড লিস্টের উপাদান প্রিন্ট করা
PRINT *, 'Linked list elements:'
temp => head
DO WHILE (ASSOCIATED(temp))
PRINT *, temp%data
temp => temp%next_node
END DO
END PROGRAM linked_list_exampleএখানে:
- Node টাইপটি একটি data (পুরানো ডেটা) এবং next_node (পয়েন্টার) ধারণ করে।
- ALLOCATE কমান্ড দিয়ে লিঙ্কড লিস্টের জন্য মেমরি বরাদ্দ করা হয়েছে এবং ASSOCIATED ফাংশন ব্যবহার করে লিঙ্কড লিস্টের প্রতিটি উপাদান একে একে প্রিন্ট করা হয়েছে।
আউটপুট:
Enter a value to insert:
20
Linked list elements:
10
20এখানে ১০ এবং ২০ মানের দুটি উপাদান যুক্ত হয়েছে, এবং এটি লিঙ্কড লিস্টের মাধ্যমে প্রদর্শিত হচ্ছে।
৩. Dynamic Data Structures (ডায়নামিক ডেটা স্ট্রাকচার)
ডায়নামিক ডেটা স্ট্রাকচারগুলি এমন স্ট্রাকচার যা ডাটা সঞ্চয় করার জন্য রানটাইমে মেমরি বরাদ্দ ও মুক্ত করে। এ ধরনের ডেটা স্ট্রাকচারগুলি অত্যন্ত নমনীয় এবং মেমরি ব্যবস্থাপনাতে আরও দক্ষ।
ডায়নামিক ডেটা স্ট্রাকচারগুলির মধ্যে সাধারণত লিঙ্কড লিস্ট, স্ট্যাক, কিউ, গ্রাফ ইত্যাদি অন্তর্ভুক্ত হয়। এদের মধ্যে কিছু বিশেষ উদাহরণ দেওয়া হল:
১. Stack (স্ট্যাক)
স্ট্যাক একটি ডেটা স্ট্রাকচার যা Last In First Out (LIFO) প্রিন্সিপলের উপর কাজ করে। অর্থাৎ, শেষ যেটি প্রবেশ করবে, সেটিই প্রথমে বের হবে।
উদাহরণ: স্ট্যাক তৈরি করা
MODULE stack_module
TYPE Node
INTEGER :: data
POINTER :: next_node => NULL()
END TYPE Node
TYPE(Node), POINTER :: top
CONTAINS
SUBROUTINE push(value)
INTEGER, INTENT(IN) :: value
TYPE(Node), POINTER :: new_node
ALLOCATE(new_node)
new_node%data = value
new_node%next_node => top
top => new_node
END SUBROUTINE push
SUBROUTINE pop()
TYPE(Node), POINTER :: temp
IF (ASSOCIATED(top)) THEN
temp => top
PRINT *, 'Popped value: ', top%data
top => top%next_node
DEALLOCATE(temp)
ELSE
PRINT *, 'Stack is empty!'
END IF
END SUBROUTINE pop
END MODULE stack_module
PROGRAM stack_example
USE stack_module
INTEGER :: value
top => NULL()
CALL push(10)
CALL push(20)
CALL push(30)
CALL pop() ! 30 will be popped
CALL pop() ! 20 will be popped
CALL pop() ! 10 will be popped
CALL pop() ! Stack is empty
END PROGRAM stack_exampleএখানে:
- push সাবরুটিন স্ট্যাকের উপরে একটি নতুন উপাদান যোগ করে।
- pop সাবরুটিন স্ট্যাক থেকে উপাদান মুছে ফেলে।
২. Queue (কিউ)
কিউ একটি First In First Out (FIFO) প্রিন্সিপলে কাজ করে। অর্থাৎ, প্রথমে যে উপাদান প্রবেশ করবে, সেটিই প্রথমে বের হবে।
উদাহরণ: কিউ তৈরি করা
MODULE queue_module
TYPE Node
INTEGER :: data
POINTER :: next_node => NULL()
END TYPE Node
TYPE(Node), POINTER :: front, rear
CONTAINS
SUBROUTINE enqueue(value)
INTEGER, INTENT(IN) :: value
TYPE(Node), POINTER :: new_node
ALLOCATE(new_node)
new_node%data = value
new_node%next_node => NULL()
IF (.NOT. ASSOCIATED(front)) THEN
front => new_node
rear => new_node
ELSE
rear%next_node => new_node
rear => new_node
END IF
END SUBROUTINE enqueue
SUBROUTINE dequeue()
TYPE(Node), POINTER :: temp
IF (ASSOCIATED(front)) THEN
temp => front
PRINT *, 'Dequeued value: ', front%data
front => front%next_node
DEALLOCATE(temp)
ELSE
PRINT *, 'Queue is empty!'
END IF
END SUBROUTINE dequeue
END MODULE queue_module
PROGRAM queue_example
USE queue_module
INTEGER :: value
front => NULL()
rear => NULL()
CALL enqueue(10)
CALL enqueue(20)
CALL enqueue(30)
CALL dequeue() ! 10 will be dequeued
CALL dequeue() ! 20 will be dequeued
CALL dequeue() ! 30 will be dequeued
CALL dequeue() ! Queue is empty
END PROGRAM queue_exampleএখানে:
- enqueue সাবরুটিন কিউতে একটি নতুন উপাদান যোগ করে।
- dequeue সাবরুটিন কিউ থেকে একটি উপাদান মুছে ফেলে।
উপসংহার
ফোরট্রানে Linked List এবং Dynamic Data Structures ব্যবহার করে ডেটা সংরক্ষণ ও পরিচালনার দক্ষতা বাড়ানো যায়। লিঙ্কড লিস্ট, স্ট্যাক এবং কিউ এই ধরনের ডায়নামিক ডেটা স্ট্রাকচারগুলির মধ্যে জনপ্রিয়। এগুলি মেমরি ব্যবস্থাপনায় আরও নমনীয় এবং কোডের কার্যকারিতা উন্নত করতে সাহায্য করে, বিশেষ করে যখন আপনি জানেন না কতটুকু মেমরি প্রয়োজন হবে বা ডেটা সাইজ পরিবর্তনশীল।
Read more